<script setup lang="ts">
import { useCartStore, useMemberStore, useRefreshStore } from '@/stores'
import { nextTick, ref, watch } from 'vue'
import type { cartItem } from '@/types/cart'
import { deleteCartApi, getCartApi, putCartApi, putCartSelectedAllApi } from '@/api/cart'
import type { InputNumberBoxEvent } from '@/components/vk-data-input-number-box/vk-data-input-number-box'
import { computed } from 'vue'
import { debounce } from 'lodash'
import { executeWithLoading, fullUrl, onShowRefreshData } from '@/utils/common'
// zpaging必须导入需要用到的页面生命周期（即使在当前页面上没有直接使用到）
import useZPagingComp from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPagingComp.js'
import { pageUrl, safeBottom } from '@/utils/constants'
import { onLoad, onShow } from '@dcloudio/uni-app'

const memberStore = useMemberStore()
const cartStore = useCartStore()

const paging = ref()
// 子组件内使用useZPagingComp
defineExpose({ ...useZPagingComp(paging) })

const props = defineProps<{
  type?: string
}>()

// 结算栏安全距离
const toolbarSafeAreaInsets = computed(() => {
  if (props.type === 'tabBar') return 0
  return safeBottom
})

// 商品列表
const cartList = ref<cartItem[]>()
const queryList = (page: number, page_size: number) => {
  getCartApi({
    page,
    page_size,
  }).then((res) => {
    paging.value.complete(res.result.data)
    cartStore.setCartTotalNum(res.result.total_num)
  })
}

//删除购物车商品
const onDeleteCart = (id: string[] | number[]) => {
  const content = id.length > 1 ? '确定要删除选中的商品吗' : '确定要删除该商品吗'

  uni.showModal({
    title: '提示',
    content: content,
    showCancel: true,
    success: async ({ confirm, cancel }) => {
      if (confirm) {
        await deleteCartApi({
          id,
        })
        uni.showToast({
          title: '删除成功',
          icon: 'success',
          mask: true,
        })
        setTimeout(() => {
          paging.value.reload()
        }, 1000)
      }
    },
  })
}

// 批量删除选择的商品
const onDeleteCartBatch = () => {
  if (!selectedList.value || selectedList.value.length === 0) {
    return uni.showToast({
      icon: 'none',
      title: '请选择要删除的商品',
    })
  }
  onDeleteCart(selectedList.value.map((item) => item.id))
}

// 移除无效的商品
const removeInvalidCart = () => {
  if (!cartList.value || cartList.value.length === 0) return

  const invalidList = cartList.value.filter((item) => item.disabled)
  if (invalidList.length === 0) {
    return uni.showToast({
      icon: 'none',
      title: '购物车内商品都是有效的噢,快去结算吧~',
    })
  }

  uni.showModal({
    title: '提示',
    content: '是否快速清理无效商品',
    showCancel: true,
    success: ({ confirm, cancel }) => {
      if (confirm) {
        uni.showLoading({
          title: '快速清理中…',
          mask: true,
        })
        setTimeout(() => {
          deleteCartApi({
            id: invalidList.map((item) => item.id),
          })
          uni.showToast({
            title: '清理完成',
            icon: 'success',
            mask: true,
          })
          uni.hideLoading()
          paging.value.reload()
        }, 1500)
      }
    },
  })
}

//修改购物车
const onChangeCart = debounce((event: InputNumberBoxEvent) => {
  putCartApi({
    id: Number(event.index),
    num: event.value,
  })
}, 500)

//修改选中状态
const onChangeSelected = debounce((item: cartItem) => {
  if (item.disabled) return
  //取反选中状态
  item.selected = !item.selected
  putCartApi({
    id: item.id,
    selected: item.selected,
  })
}, 500)

//修改全选状态
const onChangeSelectedAll = debounce(() => {
  if (!cartList.value || cartList.value.length === 0) return
  if (!effectiveCartList.value || effectiveCartList.value.length === 0) return

  //取反全选状态
  const isSelectedAllOld = isSelectedAll.value
  //更新每个商品选中状态
  cartList.value?.forEach((item) => {
    item.selected = !isSelectedAllOld
  })
  //更新到服务器
  putCartSelectedAllApi({
    selected: !isSelectedAllOld,
  })
}, 500)

//选中的购物车商品
const selectedList = computed(() => {
  return cartList.value?.filter((item) => item.selected && !item.disabled)
})

// 有效的购物车商品列表
const effectiveCartList = computed(() => {
  return cartList.value?.filter((item) => !item.disabled)
})

//购物车商品全选状态
const isSelectedAll = computed(() => {
  if (!selectedList.value || !cartList.value || selectedList.value.length <= 0) {
    return false
  }

  return selectedList.value.length === effectiveCartList.value?.length
})

//选中商品数量
const selectedCount = computed(() => {
  if (!selectedList.value) return 0

  const count = selectedList.value?.reduce((sum, item) => (sum += item.num), 0)

  return count > 99 ? '99+' : count
})

//选中商品总价
const selectedPrice = computed(() => {
  return selectedList.value?.reduce((sum, item) => (sum += item.sku.price * item.num), 0).toFixed(2)
})

//跳转支付
const gotoPayment = () => {
  if (selectedCount.value === 0) {
    return uni.showToast({
      icon: 'none',
      title: '请选择结算商品',
    })
  }
  uni.navigateTo({ url: `${pageUrl['order-create']}` })
}

const formatPrice = (price: string | number) => {
  let [integer, decimal] = price.toString().split('.')

  return {
    integer,
    decimal,
  }
}

// 跳转首页
const goToIndex = (event: any) => {
  event(false)
  uni.switchTab({
    url: `${pageUrl['index']}`,
  })
}

const totalNum = computed(() => {
  return cartList.value?.reduce((sum, item) => (sum += item.num), 0) || 0
})

onShow(() => {
  if (memberStore.profile) {
    nextTick(() => {
      paging.value?.refresh()
    })
  }
})

watch(
  () => totalNum.value,
  (newVal) => {
    cartStore.setCartTotalNum(newVal)
    // 设置购物车角标
    cartStore.setCartTabBadge()
  },
  { immediate: true, deep: true },
)
</script>

<template>
  <template v-if="memberStore.profile">
    <view class="cart-list">
      <z-paging
        ref="paging"
        v-model="cartList"
        :auto="false"
        @query="queryList"
        empty-view-text="购物车空空如也，快去逛逛看吧~"
        show-empty-view-reload
        empty-view-reload-text="去逛逛"
        @emptyViewReload="goToIndex"
        :paging-style="{
          backgroundColor: '#f7f7f8',
        }"
        :empty-view-reload-style="{
          backgroundColor: '#ff5555',
          color: 'white',
          borderRadius: '10px',
          padding: '10px 20px',
        }"
      >
        <view class="cart-operate" v-if="cartList && cartList.length > 0">
          <text class="operate-item icon icon-delete" @tap="onDeleteCartBatch">批量删除</text>
          <text class="operate-item icon icon-clear" @tap="removeInvalidCart">快速清理</text>
        </view>
        <view class="cart-list-item">
          <uni-swipe-action>
            <uni-swipe-action-item
              v-for="item in cartList"
              :key="item.sku_id"
              class="cart-swipe"
              :class="{ disabled: item.disabled }"
            >
              <view class="goods">
                <text v-if="item.disabled" class="disabled">{{ item.disabled_text }}</text>
                <text
                  v-else
                  class="checkbox"
                  :class="{ checked: item.selected }"
                  @tap="onChangeSelected(item)"
                ></text>
                <navigator
                  :url="`${pageUrl['goods-detail']}?id=${item.goods_id}`"
                  hover-class="none"
                  class="navigator"
                >
                  <image mode="aspectFill" class="picture" :src="fullUrl(item.sku.image)"></image>
                  <view class="meta">
                    <view class="name ellipsis">{{ item.goods.name }}</view>
                    <view class="attrsText ellipsis">{{ item.sku.spec_text }}</view>
                    <view class="price">
                      <span class="integer">{{ formatPrice(item.sku.price).integer }}</span>
                      <span class="decimal">.{{ formatPrice(item.sku.price).decimal }}</span>
                    </view>
                  </view>
                </navigator>
                <view class="num" v-if="!item.disabled">
                  <vk-data-input-number-box
                    v-model="item.num"
                    :index="item.id"
                    :min="1"
                    :max="item.sku.stock"
                    @plus="onChangeCart($event)"
                    @minus="onChangeCart($event)"
                    @blur="onChangeCart($event)"
                  />
                </view>
              </view>
              <template #right>
                <view class="cart-swipe-right">
                  <button class="button delete-button" @tap="onDeleteCart([item.id])">删除</button>
                </view>
              </template>
            </uni-swipe-action-item>
          </uni-swipe-action>
        </view>
        <template #bottom>
          <view class="toolbar" :style="{ paddingBottom: toolbarSafeAreaInsets + 'px' }">
            <text class="all" :class="{ checked: isSelectedAll }" @tap="onChangeSelectedAll"
              >全选</text
            >
            <view class="total-price">
              <text class="text">总计:</text>
              <text class="amount">{{ selectedPrice ?? '0.00' }}</text>
            </view>
            <view class="button-grounp">
              <view
                class="button payment-button"
                :class="{ disabled: selectedCount === 0 }"
                @tap="gotoPayment"
              >
                去结算({{ selectedCount }})
              </view>
            </view>
          </view>
          <view class="toolbar-height"></view>
        </template>
      </z-paging>
    </view>
  </template>
  <!-- 未登录: 提示登录 -->
  <view class="login-blank" v-else>
    <text class="text">登录后可查看购物车中的商品</text>
    <navigator :url="pageUrl['login']" hover-class="none">
      <button class="button">去登录</button>
    </navigator>
  </view>
</template>

<style lang="scss">
// 根元素
:host {
  height: 100%;
  display: flex;
  flex-direction: column;
  background-color: #f7f7f8;
}

.cart-operate {
  padding-top: 20rpx;
  padding-left: 20rpx;
  display: flex;
  justify-content: flex-end;

  .operate-item {
    padding-right: 20rpx;
    font-size: 28rpx;
  }
}

.cart-list {
  .tips {
    // display: flex;
    align-items: center;
    line-height: 1;
    margin: 30rpx 10rpx;
    font-size: 26rpx;
    color: #666;

    .label {
      color: #fff;
      padding: 7rpx 15rpx 5rpx;
      border-radius: 4rpx;
      font-size: 24rpx;
      background-color: #ff5f3c;
      margin-right: 10rpx;
    }
  }

  .cart-list-item {
    padding: 20rpx;
  }

  .cart-swipe.disabled {
    opacity: 0.5;
    filter: grayscale(100%);
    pointer-events: none;
  }

  // 购物车商品
  .goods {
    display: flex;
    padding: 3% 5% 3% 11%;
    border-radius: 10rpx;
    background-color: #fff;
    position: relative;

    .navigator {
      display: flex;
    }

    .disabled {
      position: absolute;
      top: 40%;
      left: 1%;
      width: 50rpx;
      font-size: 18rpx;
      text-align: center;
      background-color: #000000;
      color: white;
      padding: 3px;
      border-radius: 10px;
    }

    .checkbox {
      position: absolute;
      top: 0;
      left: 0;

      display: flex;
      align-items: center;
      justify-content: center;
      width: 80rpx;
      height: 100%;

      &::before {
        content: '\e6cd';
        font-family: 'iconfont' !important;
        font-size: 40rpx;
      }

      &.checked::before {
        content: '\e6cc';
        color: #ff5f3c;
      }
    }

    .picture {
      width: 180rpx;
      height: 180rpx;
    }

    .meta {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: space-around;
      margin-left: 20rpx;
    }

    .name {
      font-size: 26rpx;
      color: #444;
      align-items: center;
    }

    .attrsText {
      line-height: 1.8;
      margin-top: 10rpx;
      padding: 0 15rpx;
      font-size: 24rpx;
      align-self: flex-start;
      border-radius: 4rpx;
      color: #888;
      background-color: #f7f7f8;
    }

    .price {
      line-height: 2;
      color: #e33333;
      margin-bottom: 2rpx;
      display: flex;
      align-items: baseline;

      &::before {
        content: '￥';
        font-size: 20rpx;
        vertical-align: sub;
      }

      .integer {
        font-size: 30rpx;
      }

      .decimal {
        font-size: 20rpx;
      }
    }

    // 商品数量
    .num {
      position: absolute;
      bottom: 10rpx;
      right: 10rpx;

      .text {
        height: 100%;
        padding: 0 20rpx;
        font-size: 32rpx;
        color: #444;
      }

      .input {
        height: 100%;
        text-align: center;
        border-radius: 4rpx;
        font-size: 24rpx;
        color: #444;
        background-color: #f6f6f6;
      }
    }
  }

  .cart-swipe {
    display: block;
    margin: 20rpx 0;
  }

  .cart-swipe-right {
    display: flex;
    height: 100%;

    .button {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 50px;
      padding: 6px;
      line-height: 1.5;
      color: #fff;
      font-size: 26rpx;
      border-radius: 0;
    }

    .delete-button {
      background-color: #cf4444;
    }
  }
}

// 空状态
.cart-blank,
.login-blank {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  height: 60vh;
  .image {
    width: 400rpx;
    height: 281rpx;
  }
  .text {
    color: #444;
    font-size: 26rpx;
    margin: 20rpx 0;
  }
  .button {
    width: 240rpx !important;
    height: 60rpx;
    line-height: 60rpx;
    margin-top: 20rpx;
    font-size: 26rpx;
    border-radius: 60rpx;
    color: #fff;
    background-color: #ff5f3c;
  }
}

// 吸底工具栏
.toolbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: var(--window-bottom);
  z-index: 100;

  height: 100rpx;
  // padding: 0 20rpx;
  display: flex;
  align-items: center;
  border-top: 1rpx solid #ededed;
  border-bottom: 1rpx solid #ededed;
  background-color: #fff;
  box-sizing: content-box;

  .all {
    margin-left: 15rpx;
    font-size: 15px;
    color: #444;
    display: flex;
    align-items: center;
  }

  .all::before {
    font-family: 'iconfont' !important;
    content: '\e6cd';
    font-size: 40rpx;
    margin-right: 8rpx;
  }

  .checked::before {
    content: '\e6cc';
    color: #ff5f3c;
  }

  .text {
    margin-right: 8rpx;
    margin-left: 12rpx;
    color: #444;
    font-size: 14px;
  }

  .amount {
    font-size: 20px;
    color: #cf4444;

    .decimal {
      font-size: 12px;
    }

    &::before {
      content: '￥';
      font-size: 12px;
    }
  }

  .button-grounp {
    // margin-left: auto;
    display: flex;
    justify-content: space-between;
    text-align: center;
    line-height: 72rpx;
    font-size: 13px;
    color: #fff;

    .button {
      width: 240rpx;
      margin: 0 10rpx;
      border-radius: 72rpx;
    }

    .payment-button {
      background-color: #ff5f3c;

      &.disabled {
        opacity: 0.6;
      }
    }
  }

  .total-price {
    //靠右对齐
    margin-left: auto;
  }
}
// 底部占位空盒子
.toolbar-height {
  height: 100rpx;
}
</style>
